package cn.com.open.itembank.service.impl;

import cn.com.open.itembank.common.GlobalConst;
import cn.com.open.itembank.common.enums.ItemType;
import cn.com.open.itembank.common.enums.SysState;
import cn.com.open.itembank.common.enums.YesOrNo;
import cn.com.open.itembank.dto.QuestionTypeDto;
import cn.com.open.itembank.dto.QuestionTypeManageDto;
import cn.com.open.itembank.dto.ReturnModel;
import cn.com.open.itembank.entity.CourseItemBank;
import cn.com.open.itembank.entity.QuestionType;
import cn.com.open.itembank.entity.QuestionTypeUseRelation;
import cn.com.open.itembank.mapper.QuestionTypeMapper;
import cn.com.open.itembank.redis.RedisConfig;
import cn.com.open.itembank.service.ItemBankService;
import cn.com.open.itembank.service.QuestionTypeService;
import cn.com.open.itembank.utils.DateUtil;
import cn.com.open.itembank.utils.RegxUtil;
import cn.com.open.itembank.utils.StringUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

/**
 * Created by lucky on 2017/8/10.
 */
@Service
public class QuestionTypeServiceImpl implements QuestionTypeService {
    private static int guidLength = 36;

    @Autowired
    private QuestionTypeMapper mapper;

    @Autowired
    private ItemBankService itemBankService;

    @Autowired
    private RedisConfig redis;

    //region 获取指定题型信息

    /**
     * 根据题型id获取题型信息.
     *
     * @param id 题型id
     * @return 题型信息
     */
    @Override
    public QuestionType getQuestionType(String id) {
        if (StringUtil.isEmpty(id) || id.length() != guidLength) {
            return null;
        }
        return mapper.getById(id);
    }

    /**
     * 根据大题id获取题型信息.
     *
     * @param sectionId 大题id
     * @return 题型信息
     */
    @Override
    public QuestionType getQuestionTypeBySectionId(String sectionId) {
        if (StringUtil.isEmpty(sectionId)) {
            return null;
        }
        RegxUtil regxUtil = new RegxUtil();
        if (regxUtil.regx(sectionId)) {
            QuestionType questionType = mapper.getByQuestionTypeId(sectionId);
            return mapper.getBySectionId(questionType.getSectionID());
        } else if (!regxUtil.judgeContainsStr(sectionId)) {
            QuestionType questionType = mapper.getByQuestionInnerTypeId(Integer.valueOf(sectionId));
            return mapper.getBySectionId(questionType.getSectionID());
        } else {
            return mapper.getBySectionId(sectionId);
        }
}

    /**
     * 根据题型id获取题型使用关系信息.
     *
     * @param id         题型id
     * @param itemBankId 题库id
     * @param appId      appid
     * @return 题型使用关系信息
     */
    private QuestionTypeUseRelation getQuestionTypeUseRelation(String id, String itemBankId, String appId) {
        if (StringUtil.isEmpty(id)) {
            return null;
        }
        return mapper.getRelationById(id, itemBankId, appId);
    }
    //endregion

    //region 获取各类列表

    /**
     * 根据题库ID获取题型列表.
     *
     * @param itemBankId 题库id
     * @return 题型列表
     */
    @Override
    public List<QuestionType> getListByItemBankId(String itemBankId) {
        //判断题库课程是否存在
        CourseItemBank itemBank = itemBankService.getCourseItemBankInfo(itemBankId);
        if (itemBank == null) {
            return new ArrayList<>();
        }

        return mapper.getListByItemBankId(itemBankId, itemBank.getAppID(), false, "");
    }

    /**
     * 根据题库ID获取题型列表(admin).
     *
     * @param itemBankId 题库id
     * @param name       题型名称模糊查询
     * @return the list by item bank id and name
     */
    @Override
    public List<QuestionTypeManageDto> getListByItemBankIdAndName(String itemBankId, String name) {
        //判断题库课程是否存在
        CourseItemBank itemBank = itemBankService.getCourseItemBankInfo(itemBankId);
        if (itemBank == null) {
            return new ArrayList<>();
        }

        return mapper.getListByItemBankIdAndName(itemBankId, itemBank.getAppID(), true, name);
    }
    //endregion

    //region 各类是否和存在判断

    /**
     * 根据内部题型id和大题序号判断数据是否存在.
     *
     * @param innerTypeId  内部题型ID
     * @param serialNumber 大题序号
     * @return 是否存在：true，存在；false，不存在；
     */
    private boolean isExistByInnerTypeIdAndSn(int innerTypeId, int serialNumber) {
        return (mapper.getCountByInnerTypeIdAndSn(innerTypeId, serialNumber) > 0);
    }

    /**
     * 根据题型名称判断数据是否存在.
     *
     * @param name 题型名称
     * @return 是否存在：true，存在；false，不存在；
     */
    private boolean isExistByName(String name) {
        return (mapper.getCountByName(name) > 0);
    }

    /**
     * 根据内部题型ID,题型ID和题型名称，判断是否存在数据.
     *
     * @param innerTypeId appKey
     * @param id          题型ID
     * @param name        题型名称
     * @return the boolean
     */
    private boolean isExistQuestionTypeName(int innerTypeId, String id, String name) {
        int cnt = mapper.isExistQuestionTypeName(innerTypeId, id, name);

        return cnt > 0;
    }
    //endregion

    //region 新增题型

    /**
     * 新增题型.
     *
     * @param itemBankId 所属题库id
     * @param model      题型传输模型
     * @return the return model
     */
    @Override
    public ReturnModel insert(String itemBankId, QuestionTypeDto model) {
        ReturnModel returnModel = new ReturnModel();
        int ret = GlobalConst.SUCCESS;

        if (model == null || itemBankId.length() != guidLength || StringUtil.isEmpty(model.getQuestionTypeName())) {
            returnModel.setCode(GlobalConst.DATA_FORMAT_ERROR);
            returnModel.setMessage("参数不完整");
            return returnModel;
        }

        //判断内部题型是否可以设定题型
        if (!checkQtiType(model.getQuestionInnerTypeID())) {
            returnModel.setCode(GlobalConst.IS_NOT_SUPPORTED_INNER_TYPE);
            returnModel.setMessage("内部题型不支持创建新题型");
            return returnModel;
        }

        //判断大题编号的序号是否重复
        if (isExistByInnerTypeIdAndSn(model.getQuestionInnerTypeID(), model.getSerialNumber())) {
            returnModel.setCode(GlobalConst.SERIAL_NUMBER_EXIST);
            returnModel.setMessage("大题编号重复");
            return returnModel;
        }

        //检查题库是否存在
        CourseItemBank itemBank = itemBankService.getCourseItemBankInfo(itemBankId);
        if (itemBank == null) {
            returnModel.setCode(GlobalConst.COURSE_NOT_EXIST);
            returnModel.setMessage("题库不存在");
            return returnModel;
        }

        //检查名称是否重复
        if (isExistByName(model.getQuestionTypeName())) {
            returnModel.setCode(GlobalConst.DATA_EXIST);
            returnModel.setMessage("题型名称已经存在");
            return returnModel;
        }

        QuestionType questionType = new QuestionType();
        questionType.setQuestionInnerTypeID(model.getQuestionInnerTypeID());
        questionType.setDirections(model.getDirections());
        questionType.setQuestionTypeName(model.getQuestionTypeName());
        questionType.setSerialNumber(model.getSerialNumber());
        questionType.setQuestionTypeID(UUID.randomUUID().toString());
        questionType.setSectionID(String.format("S%s-%s", model.getQuestionInnerTypeID(), model.getSerialNumber()));

        mapper.insert(questionType);

        QuestionTypeUseRelation relation = new QuestionTypeUseRelation();
        relation.setID(UUID.randomUUID().toString());
        relation.setQuestionTypeID(questionType.getQuestionTypeID());
        relation.setItemBankID(itemBankId);
        relation.setIsDefault(YesOrNo.NO.getIndex());
        relation.setStatus(SysState.START.getIndex());
        relation.setCreater(GlobalConst.EMPTYUUID);
        relation.setCreateTime(DateUtil.getCurrentTimeToShowString());
        //默认不共享
        relation.setIsAppShare(YesOrNo.NO.getIndex());
        relation.setAppID(GlobalConst.EMPTYID);
        //如果传输模型设置为共享，则调整为共享，共享后appid设置为itembank所属的appid
        if (model.getIsShare() == YesOrNo.YES.getIndex()) {
            relation.setIsAppShare(YesOrNo.YES.getIndex());
            relation.setAppID(itemBank.getAppID());
        }

        mapper.insertRelation(relation);

        returnModel.setCode(ret);
        return returnModel;
    }
    //endregion

    //region 修改题型

    /**
     * 修改题型
     *
     * @param id         题型
     * @param itemBankId 所属题库id
     * @param model      the model
     * @return the int
     */
    @Override
    public int update(String id, String itemBankId, QuestionTypeDto model) {
        if (model == null || id.length() != guidLength || itemBankId.length() != guidLength || StringUtil.isEmpty(model.getQuestionTypeName())) {
            return GlobalConst.DATA_FORMAT_ERROR;
        }

        //判断题库课程是否存在
        CourseItemBank itemBank = itemBankService.getCourseItemBankInfo(itemBankId);
        if (itemBank == null) {
            return GlobalConst.COURSE_NOT_EXIST;
        }

        //判断题型是否存在
        QuestionType questionType = mapper.getById(id);
        if (questionType == null) {
            return GlobalConst.ID_NOT_EXIST;
        }

        //拒绝修改默认题型
        QuestionTypeUseRelation relation = getQuestionTypeUseRelation(id, itemBankId, itemBank.getAppID());
        if (relation == null || relation.getIsDefault() == YesOrNo.YES.getIndex()) {
            return GlobalConst.NO_PERMISSION;
        }

        // 检查是否重名
        if (isExistQuestionTypeName(model.getQuestionInnerTypeID(), id, model.getQuestionTypeName())) {
            return GlobalConst.DATA_EXIST;
        }

        try {
            //修改名称和说明
            mapper.update(id, model.getQuestionTypeName(), model.getDirections());
            //根据共享状态修改共享属性和appid
            String appId = GlobalConst.EMPTYID;
            if (model.getIsShare() == YesOrNo.YES.getIndex()) {
                appId = itemBank.getAppID();
            }
            mapper.updateRelation(id, itemBankId, appId, model.getIsShare());

            return GlobalConst.SUCCESS;
        } catch (Exception e) {
            return GlobalConst.DATA_BASE_ERROR;
        }
    }

    /**
     * 更新题型状态.
     *
     * @param id         题型
     * @param itemBankId 所属题库id
     * @return the int
     */
    @Override
    public int changeStatus(String id, String itemBankId) {
        if (id.length() != guidLength || itemBankId.length() != guidLength) {
            return GlobalConst.DATA_FORMAT_ERROR;
        }

        //判断题库课程是否存在
        CourseItemBank itemBank = itemBankService.getCourseItemBankInfo(itemBankId);
        if (itemBank == null) {
            return GlobalConst.COURSE_NOT_EXIST;
        }

        //判断题型是否存在
        QuestionType questionType = mapper.getById(id);
        if (questionType == null) {
            return GlobalConst.ID_NOT_EXIST;
        }

        //拒绝修改默认题型和app共享题型
        QuestionTypeUseRelation relation = getQuestionTypeUseRelation(id, itemBankId, itemBank.getAppID());
        if (relation == null || relation.getIsDefault() == YesOrNo.YES.getIndex() || relation.getIsAppShare() == YesOrNo.YES.getIndex()) {
            return GlobalConst.NO_PERMISSION;
        }

        int oldStatus = relation.getStatus();

        int newStatus = (oldStatus == SysState.START.getIndex()) ? SysState.STOP.getIndex() : SysState.START.getIndex();

        try {
            mapper.changeStatus(id, newStatus);
            return GlobalConst.SUCCESS;
        } catch (Exception e) {
            return GlobalConst.DATA_BASE_ERROR;
        }
    }
    //endregion

    //region 删除题型

    /**
     * 删除题型.
     *
     * @param id         题型ID
     * @param itemBankId 所属题库ID
     * @return the int
     */
    @Override
    public int delete(String id, String itemBankId) {
        //判断题库课程是否存在
        CourseItemBank itemBank = itemBankService.getCourseItemBankInfo(itemBankId);
        if (itemBank == null) {
            return GlobalConst.COURSE_NOT_EXIST;
        }

        // 检查题型是否存在
        QuestionTypeUseRelation model = getQuestionTypeUseRelation(id, itemBankId, itemBank.getAppID());
        if (model == null) {
            return GlobalConst.ID_NOT_EXIST;
        }

        // 检查题型是否为共享题型
        if (model.getIsDefault() == YesOrNo.YES.getIndex() || model.getIsAppShare() == YesOrNo.YES.getIndex()) {
            return GlobalConst.NO_PERMISSION;
        }

        // 判断该题型是否关联试题，如果关联不予删除
        if (mapper.getQuestionCount(id, itemBankId) > 0) {
            return GlobalConst.DATA_EXIST;
        }

        try {
            mapper.deleteByItemBankId(id, itemBankId);
            return GlobalConst.SUCCESS;
        } catch (Exception e) {
            return GlobalConst.DATA_BASE_ERROR;
        }
    }

    /**
     * 恢复标记删除的修改题型使用关系状态.
     *
     * @param id         题型ID
     * @param itemBankId 所属题库ID
     * @return the int
     */
    @Override
    public int deleteRollback(String id, String itemBankId) {
        //判断题库课程是否存在
        CourseItemBank itemBank = itemBankService.getCourseItemBankInfo(itemBankId);
        if (itemBank == null) {
            return GlobalConst.COURSE_NOT_EXIST;
        }

        // 判断该题型是否关联试题，如果关联不予删除
        if (mapper.getQuestionCount(id, itemBankId) > 0) {
            return GlobalConst.DATA_EXIST;
        }

        try {
            mapper.deleteRollBackByItemBankId(id, itemBankId);
            return GlobalConst.SUCCESS;
        } catch (Exception e) {
            return GlobalConst.DATA_BASE_ERROR;
        }
    }
    //endregion

    //region 内部方法

    /**
     * 判断内部题型是否可以设定题型
     *
     * @param innerTypeId the inner type id
     * @return the boolean
     */
    private boolean checkQtiType(int innerTypeId) {
        switch (ItemType.fromValue(innerTypeId)) {
            case UNKNOW:
            case COMPOSITEMULTIPLECHOICE:
            case COMPOSITESINGLECHOICE:
                return false;
            default:
                return true;
        }
    }
    //endregion

}
